/**
 * @Author: Jiang Zhongxun
 * @Date: 2024-10-03 22:12:17
 * @FilePath: /Socket/practiceProject/src/db/dbDefinition.c
 * @Description: SQLite3数据库定义相关接口
 */
#include "../../include/db/dbDefinition.h"

sqlite3 *db = NULL; // 操作数据库的句柄

/**
 * 创建数据库接口
 *
 * @param null
 * @return 返回操作数据库的句柄db，失败返回NULL
 */
sqlite3 *createDatabase(void)
{
    char fullPath[256] = {0};
    snprintf(fullPath, sizeof(fullPath), "%s/%s", DATABASE_PATH, DATABASE_NAME);
    // printf("fullPath = %s\n", fullPath);
    // sqlite3 *db = NULL;
    int ret = sqlite3_open(fullPath, &db);
    if (SQLITE_OK != ret)
    {
        perror("create database error");
        return NULL;
    }
    // 设置 busy timeout 为 5000 毫秒（5秒）
    sqlite3_busy_timeout(db, 3000); // 等待最多 5 秒
    // 如果需要，设置 WAL 模式，防止锁冲突
    int rc = sqlite3_exec(db, "PRAGMA journal_mode=WAL;", NULL, NULL, NULL);
    if (rc != SQLITE_OK)
    {
        fprintf(stderr, "Failed to set WAL mode: %s\n", sqlite3_errmsg(db));
    }
    // printf("create database ok!\n");
    return db;
}

/**
 * 创建用户信息表接口
 *
 * @param db SQLite3数据库指针
 * @return 返回0表示成功，非零表示失败
 */
int createUserInfoTable(sqlite3 *db)
{
    char *errmsg = NULL;
    char sql[512] = {0};
    sprintf(sql, "CREATE TABLE IF NOT EXISTS %s \
    (userId INTEGER PRIMARY KEY AUTOINCREMENT, \
    userName TEXT NOT NULL, \
    passwd TEXT DEFAULT '123456', \
    userType INTEGER NOT NULL DEFAULT 1 CHECK(userType IN (0, 1)), \
    createTime TEXT DEFAULT (datetime('now', 'localtime')), \
    updateTime TEXT DEFAULT (datetime('now', 'localtime')), \
    isDelete INTEGER NOT NULL DEFAULT 0 \
    );",
            USER_TABLE_NAME);
    // printf("SQL语句: %s\n", sql);
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (SQLITE_OK != ret)
    {
        perror("create userInfo table error");
        sqlite3_free(errmsg);
        return -1;
    }
    // printf("create userInfo table ok!\n");
    return 0;
}

/**
 * 创建日志信息表接口
 *
 * @param db SQLite3数据库指针
 * @return 返回0表示成功，非零表示失败
 */
int createLogInfoTable(sqlite3 *db)
{
    char *errmsg = NULL;
    char sql[512] = {0};
    sprintf(sql, "CREATE TABLE IF NOT EXISTS %s \
    (logId INTEGER PRIMARY KEY AUTOINCREMENT, \
    logMsg TEXT NOT NULL, \
    logType INTEGER DEFAULT 0 NOT NULL CHECK(logType IN (0, 1)), \
    createTime TEXT DEFAULT (datetime('now', 'localtime')), \
    updateTime TEXT DEFAULT (datetime('now', 'localtime')), \
    isDelete INTEGER NOT NULL DEFAULT 0 \
    );",
            LOG_TABLE_NAME);
    // printf("SQL语句: %s\n", sql);
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (SQLITE_OK != ret)
    {
        perror("create logInfo table error");
        sqlite3_free(errmsg);
        return -1;
    }
    // printf("create logInfo table ok!\n");
    return 0;
}

/**
 * 创建查验记录信息表接口
 *
 * @param db SQLite3数据库指针
 * @return 返回0表示成功，非零表示失败
 */
int createCheckInfoTable(sqlite3 *db)
{
    char *errmsg = NULL;
    char sql[512] = {0};
    sprintf(sql, "CREATE TABLE IF NOT EXISTS %s \
    (checkId INTEGER PRIMARY KEY AUTOINCREMENT, \
    checkItemName TEXT NOT NULL, \
    applyUser TEXT NOT NULL, \
    checker TEXT NOT NULL DEFAULT 'system', \
    checkStatus INTEGER DEFAULT 0 NOT NULL CHECK(checkStatus IN (0, 1, 2)), \
    checkType INTEGER DEFAULT 0 NOT NULL CHECK(checkType IN (0, 1)), \
    createTime TEXT DEFAULT (datetime('now', 'localtime')), \
    updateTime TEXT DEFAULT (datetime('now', 'localtime')), \
    isDelete INTEGER NOT NULL DEFAULT 0 \
    );",
            CHECK_TABLE_NAME);
    // printf("SQL语句: %s\n", sql);
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if (SQLITE_OK != ret)
    {
        perror("create checkInfo table error");
        sqlite3_free(errmsg);
        return -1;
    }
    // printf("create checkInfo table ok!\n");
    return 0;
}

/**
 * 初始化数据库接口
 *
 * @param null
 * @return db 返回操作数据库的句柄
 */
sqlite3 *databaseInit(void)
{
    // 创建数据库
    sqlite3 *db = createDatabase();
    if (NULL == db)
    {
        perror("init create database error");
        return NULL;
    }
    // 创建用户信息表
    if (0 != createUserInfoTable(db))
    {
        perror("init create userInfo table error");
        return NULL;
    }
    // 创建日志信息表
    if (0 != createLogInfoTable(db))
    {
        perror("init create logInfo table error");
        return NULL;
    }
    // 创建查验记录信息表
    if (0 != createCheckInfoTable(db))
    {
        perror("init create checkInfo table error");
        return NULL;
    }
    return db;
}
